home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / conqsrc.lha / Conquest / src / enemy.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-03  |  12.9 KB  |  602 lines

  1. /* Enemy.c: Routines for the enemy player */
  2. #include <stdio.h>
  3. #include "defs.h"
  4. #include "structs.h"
  5. #include "vars.h"
  6. #include "protos.h"
  7.  
  8. /* Return TRUE if we should all flee from this battle */
  9. boolean best_withdraw_plan(int starnum, float enodds)
  10. {
  11.   tplanet *pplanet;
  12.   int size;
  13.   tteam team;
  14.  
  15.   team = none;
  16.   size = 0;
  17.   for (pplanet = stars[starnum].first_planet; pplanet; pplanet = pplanet->next)
  18.   {
  19.     if ( pplanet->capacity > size ) 
  20.     {
  21.       size = pplanet->capacity;
  22.       team = pplanet->team;
  23.     }
  24.   }
  25.   
  26.   if (((enodds<0.70) && (size<30)) ||
  27.       ((enodds<0.50) && (team==player)) ||
  28.       ((enodds<0.30) && (size<60)) ||
  29.       ( enodds<0.20)) 
  30.     return(TRUE);
  31.   else 
  32.     return(FALSE);
  33. }
  34.  
  35. /* Enemy attack at a planet */
  36. void enemy_attack(int starnum)
  37. {
  38.   int attack_factors,def_factors;  
  39.   float odds,best_score;
  40.   struct stplanet *pplanet,*best_planet; 
  41.   int en_tf,i;
  42.   boolean first[8];
  43.   
  44.   for (i = 1 ; i<=7; i++)
  45.     first[i] = true;
  46.  
  47.   en_tf = 1;
  48.   while ((tf[ENEMY][en_tf].dest!=starnum) || 
  49.      (tf[ENEMY][en_tf].eta != 0 ))
  50.     en_tf++;
  51.  
  52.   do
  53.   {
  54.     attack_factors = tf[ENEMY][en_tf].c + 6*tf[ENEMY][en_tf].b;
  55.  
  56.     best_planet = nil;
  57.     best_score = 1000;
  58.  
  59.     /* Calculate the best one to attack */
  60.     for (pplanet = stars[starnum].first_planet; pplanet != NULL;
  61.      pplanet = pplanet->next)
  62.     {
  63.       if (pplanet->team == player) 
  64.       {
  65.     def_factors = pplanet->esee_def;
  66.  
  67.     odds = (float)def_factors / attack_factors;
  68.  
  69.     if (pplanet->capacity > 30)
  70.       odds = (odds - 2) * pplanet->capacity;
  71.     else
  72.       odds = (odds - 1.5) * pplanet->capacity;
  73.  
  74.     if (odds < best_score) 
  75.     {
  76.       best_score = odds;
  77.       best_planet = pplanet;
  78.     }
  79.       }
  80.     }
  81.  
  82.     /* Found one that was worth attacking */
  83.     if (best_score < 0) 
  84.     {
  85.       clear_left();
  86.       point(1,19);
  87.       printf("Enemy attacks: %c%d", starnum+'A'-1, 
  88.          best_planet->number);
  89.       point(50,1);
  90.       print_star(starnum);
  91.       clear_field();
  92.       pause();
  93.  
  94.       fire_salvo(ENEMY, en_tf, best_planet, first[best_planet->number]);
  95.  
  96.       first[best_planet->number] = false;
  97.       zero_tf(ENEMY,en_tf);
  98.       best_planet->esee_def = best_planet->mb + 6*best_planet->amb;
  99.  
  100.       pause();
  101.     }
  102.   } 
  103.   while ((best_score < 0) && any_bc(ENEMY, starnum));
  104.  
  105.   revolt(starnum);
  106. }
  107.  
  108. void depart(int starnum)
  109. {
  110.   if ((tf_stars[starnum][player] + col_stars[starnum][player]) > 0)
  111.     en_departures[starnum]=true;
  112. }
  113.  
  114. /* How much do we care about moving ships to this planet */
  115. int eval_bc_col(struct stplanet *planet)
  116. {
  117.   int result;
  118.  
  119.   if (!(stars[planet->pstar].visit[ENEMY]))
  120.     result = 600;
  121.   else 
  122.   {
  123.     switch (planet->esee_team)
  124.     {
  125.      case none:
  126.       result=100; 
  127.       break;
  128.      case ENEMY:
  129.       if (planet->conquered)
  130.     result = 1000;
  131.       else 
  132.       {    
  133.     if (((6*planet->amb + planet->mb) <= (planet->iu/15)) && 
  134.         (planet->iu >= mb_cost))
  135.       result = 300;
  136.     else 
  137.       result = 0;
  138.       }
  139.       
  140.       if (planet->amb >= 4)
  141.     result = result - 250;
  142.       
  143.       break;
  144.       
  145.      case player:
  146.       if (planet->conquered) 
  147.     result = 400;
  148.       else 
  149.     result = 200;
  150.       break;
  151.     }
  152.  
  153.     if ((planet->capacity < 40) && (planet->iu < 15))
  154.       result = result - 100;
  155.   }
  156.   result = result + rnd(20);
  157.   return (result);
  158. }
  159.  
  160. int eval_t_col(struct stplanet *planet, float range)
  161. {
  162.   int result;
  163.  
  164.   if (!stars[planet->pstar].visit[ENEMY])
  165.     result=60;
  166.   else 
  167.   {
  168.     switch (planet->esee_team)
  169.     {
  170.      case none: 
  171.       result = 40;
  172.       break;
  173.      case ENEMY: 
  174.       result= 30;
  175.       break;
  176.      case player: 
  177.       result = 0;
  178.     }
  179.     if ((planet->esee_team != player) && 
  180.     (planet->capacity-planet->inhabitants > 40-(turn/2)))
  181.       result = result + 40;
  182.   }
  183.  
  184.   result -= (int)(2*range + .5);
  185.  
  186.   return(result);
  187. }
  188.  
  189. void inputmach()
  190. {
  191.   int tfnum,starnum;
  192.   float slist[MAX_NUM_STARS+1];
  193.   
  194.   for (tfnum = 1 ; tfnum<=26; tfnum++) 
  195.   {
  196.     if ((tf[ENEMY][tfnum].eta==0) && (tf[ENEMY][tfnum].dest!=0)) 
  197.     {
  198.       starnum = tf[ENEMY][tfnum].dest;
  199.       get_stars(starnum,slist);
  200.       send_scouts(slist,&tf[ENEMY][tfnum]);
  201.       send_transports(slist,&tf[ENEMY][tfnum]);
  202.       move_bc(&tf[ENEMY][tfnum],slist);
  203.       zero_tf(ENEMY,tfnum);
  204.     }
  205.   }
  206. }
  207.  
  208. void move_bc(struct sttf *task, float slist[])
  209. {
  210.   int best_star, top_score, starnum, score, factors;
  211.   struct stplanet *pplanet, *best_planet;
  212.   
  213.   if ((task->b>0) || (task->c > 0)) 
  214.   {
  215.     for (starnum = 1; starnum <= nstars; starnum++)
  216.     {
  217.       if (slist[starnum] > 0)
  218.       {
  219.     best_star = starnum;
  220.     break;
  221.       }
  222.     }
  223.  
  224.     best_planet = NULL;
  225.     top_score = -1000;
  226.  
  227.     for (starnum = 1; starnum<=nstars; starnum++) 
  228.     {
  229.       if ((slist[starnum] > 0) || (starnum==task->dest)) 
  230.       {
  231.     pplanet = stars[starnum].first_planet;
  232.     while (pplanet != NULL )
  233.     {
  234.       score = eval_bc_col(pplanet) ;
  235.       if (starnum == task->dest)
  236.         score += 250;
  237.       
  238.       if (tf_stars[starnum][ENEMY] > 0)
  239.         score -= 150;
  240.       
  241.       if (score > top_score)
  242.       {
  243.         top_score = score;
  244.         best_planet = pplanet;
  245.         best_star = starnum;
  246.       }
  247.       pplanet = pplanet->next;
  248.     }
  249.       }
  250.     }
  251.     if (best_star == task->dest)
  252.     { /* stay put */
  253.       if ((best_planet != NULL) &&
  254.       (best_planet->team == ENEMY) &&
  255.       (best_planet->conquered))
  256.       {
  257.     if (best_planet->iu < 20) /* Blast it! */
  258.     {
  259.       factors = weapons[ENEMY] * ((task->c*c_guns)+(task->b*b_guns));
  260.       factors = min(factors, 4 * best_planet->inhabitants);
  261.       blast(best_planet,factors);
  262.       if ((tf_stars[best_planet->pstar][player] > 0) ||
  263.           (col_stars[best_planet->pstar][player] > 0))
  264.         best_planet->psee_capacity = best_planet->capacity;
  265.     } 
  266.     else
  267.     { /* Decide whether to split*/
  268.       if ((((task->b > 3) || (task->c > 3)) && (rnd(4)==4)) ||
  269.           (task->b > 8))
  270.         wander_bc(task,slist);
  271.     }
  272.       }
  273.     } 
  274.     else 
  275.     { /*move*/
  276.       tf_stars[task->dest][ENEMY]--;
  277.       depart(task->dest);
  278.       task->dest = best_star;
  279.       task->eta = (int)((slist[best_star]-0.01)/vel[ENEMY])+1;
  280.     }
  281.   }
  282. }
  283.  
  284. void send_transports(float slist[], struct sttf *task)
  285. {
  286.   int new_tf, to_land, sec_star, sec_score, best_star, top_score,
  287.   score,starnum;
  288.   struct stplanet *pplan, *best_plan;
  289.   int trash;
  290.   
  291.   if (task->t > 0)
  292.   {
  293.     best_star = 0;
  294.     sec_star = 0;
  295.     sec_score = -11000;
  296.     top_score = -10000;
  297.     best_plan = nil;
  298.  
  299.     for (starnum = 1; starnum<=nstars; starnum++) 
  300.     {
  301.       if ((slist[starnum] > 0) || (starnum == task->dest))
  302.       {
  303.     pplan = stars[starnum].first_planet;
  304.     while (pplan != nil) 
  305.     {
  306.       score = eval_t_col(pplan,slist[starnum]);
  307.       if (score > sec_score)
  308.       {
  309.         if (score > top_score)
  310.         {
  311.           sec_score = top_score;
  312.           sec_star = best_star;
  313.           top_score = score;
  314.           best_star = starnum;
  315.           best_plan = pplan;
  316.         }
  317.         else
  318.         {
  319.           sec_score = score;
  320.           sec_star = starnum;
  321.         }
  322.       }
  323.       pplan = pplan->next;
  324.     }
  325.       }
  326.     } /* For */
  327.  
  328.     if (best_star == task->dest)
  329.     { /* Land */
  330.       if ((tf_stars[best_star][player]==0) && (best_plan->team != player))
  331.       {
  332.     trash = (best_plan->capacity - best_plan->inhabitants)/3;
  333.     to_land = min(task->t, trash);
  334.  
  335.     if (to_land > 0)
  336.     {
  337.       if (best_plan->inhabitants == 0)
  338.       {
  339.         best_plan->team = ENEMY;
  340.         best_plan->esee_team = ENEMY;
  341.         col_stars[best_star][ENEMY]++;
  342.       }
  343.  
  344.       best_plan->inhabitants += to_land;
  345.       best_plan->iu += to_land;
  346.       task->t -= to_land;
  347.       send_transports(slist, task);
  348.     }
  349.       }
  350.     } 
  351.     else 
  352.     { /* Move */
  353.       if ((task->t >= 10) && (sec_star > 0))
  354.       { /* First send half to the best star, if two stars */
  355.     new_tf = get_tf(ENEMY,task->dest);
  356.     tf[ENEMY][new_tf].t = task->t/2;
  357.     task->t = task->t-tf[ENEMY][new_tf].t;
  358.  
  359.     if ((task->c > 0) && (!underdefended(task->dest)))
  360.     {
  361.       tf[ENEMY][new_tf].c = 1;
  362.       task->c--;
  363.     }
  364.  
  365.     send_t_tf(&tf[ENEMY][new_tf],slist,best_star);
  366.     best_star = sec_star;
  367.       }
  368.  
  369.       new_tf = get_tf(ENEMY,task->dest);
  370.       tf[ENEMY][new_tf].t = task->t;
  371.       task->t = 0;
  372.  
  373.       if ((task->c > 0) && (!underdefended(task->dest)))
  374.       {
  375.     tf[ENEMY][new_tf].c = 1;
  376.     task->c--;
  377.       }
  378.       send_t_tf(&tf[ENEMY][new_tf], slist, best_star);
  379.     }
  380.   }
  381. }
  382.  
  383. void send_t_tf(struct sttf *task, float slist[], int dest_star)
  384. {
  385.   depart(task->dest);
  386.   task->dest = dest_star;
  387.   task->eta = (int)((slist[dest_star]-0.01)/vel[ENEMY])+1;
  388. }
  389.  
  390. void send_scouts(float slist[], struct sttf *task)
  391. {
  392.   int dest, new_tf, j, doind;
  393.   int doable[MAX_NUM_STARS+1];
  394.  
  395.   if (task->s > 0) 
  396.   {
  397.     doind=0;
  398.     for (j = 1; j<=nstars; j++)
  399.     {
  400.       if ((!stars[j].visit[ENEMY]) && (slist[j]>0))
  401.       {
  402.     doind++;
  403.     doable[doind]=j;
  404.       }
  405.     }
  406.  
  407.     while ((doind>0) && (task->s > 0))
  408.     {
  409.       new_tf = get_tf(ENEMY,task->dest);
  410.       tf[ENEMY][new_tf].s = 1;
  411.       dest = rnd(doind);
  412.  
  413.       tf[ENEMY][new_tf].dest = doable[dest];
  414.       tf[ENEMY][new_tf].eta = (int)((slist[doable[dest]]-0.01)/vel[ENEMY])+1;
  415.       depart(task->dest);
  416.       doable[dest] = doable[doind];
  417.       doind--;
  418.       task->s--;
  419.     }
  420.  
  421.     while (task->s > 0)
  422.     {
  423.       do
  424.       {
  425.     dest = rnd(nstars);
  426.       } 
  427.       while (slist[dest] <= 0);
  428.  
  429.       new_tf = get_tf(ENEMY,task->dest);
  430.       tf[ENEMY][new_tf].s = 1;
  431.       tf[ENEMY][new_tf].dest = dest;
  432.       tf[ENEMY][new_tf].eta = (int)((slist[dest]-0.01)/vel[ENEMY])+1;
  433.       depart(task->dest);
  434.       task->s--;
  435.     }
  436.   }
  437. }
  438.  
  439. boolean underdefended(int starnum)
  440. {
  441.   struct stplanet *pplanet;
  442.   boolean result;
  443.   result = false;
  444.  
  445.   pplanet = stars[starnum].first_planet;
  446.   while ((pplanet != NULL) && (!result))
  447.   {
  448.     if ((pplanet->team==ENEMY) && (pplanet->iu > 10) &&
  449.     ((6*pplanet->amb+pplanet->mb) < round(pplanet->iu/15.0)))
  450.       return(TRUE);
  451.     pplanet = pplanet->next;
  452.   }
  453.   return(FALSE);
  454. }
  455.  
  456. void wander_bc(struct sttf *task, float slist[])
  457. {
  458.   int ships,i,count,dest,new_tf;
  459.  
  460.   if ((task->b > 1) || (task->c > 1))
  461.   {
  462.     count = 0;
  463.     for (i = 1 ; i<=nstars; i++)
  464.     {
  465.       if (slist[i] != 0)
  466.     count++;
  467.     }
  468.     if (count > 0) 
  469.     {
  470.       dest = rnd(count);
  471.       for (count = 0, i = 0; count != dest; i++)
  472.     if (slist[i]>0) count++;
  473.  
  474.        new_tf = get_tf(ENEMY, task->dest);
  475.  
  476.       ships = task->b/2;
  477.       tf[ENEMY][new_tf].b = ships;
  478.       task->b = task->b - ships;
  479.  
  480.       ships = task->c/2;
  481.       tf[ENEMY][new_tf].c = ships;
  482.       task->c = task->c - ships;
  483.       
  484.       if (task->t > 3) 
  485.       {
  486.     tf[ENEMY][new_tf].t = 2;
  487.     task->t = task->t-2;
  488.       }
  489.       
  490.       tf[ENEMY][new_tf].dest = i;
  491.       tf[ENEMY][new_tf].eta = (int)((slist[i]-0.01)/vel[ENEMY])+1;
  492.       depart(task->dest);
  493.     }
  494.   }
  495. }
  496.  
  497. void inv_enemy(int x, int y, struct stplanet *planet)
  498. {
  499.   int inv_amount,balance,min_mb,transports,new_tf;
  500.   
  501.   balance = planet->iu;
  502.   if (tf_stars[planet->pstar][ENEMY] == 0)
  503.   {
  504.     new_tf = get_tf(ENEMY,planet->pstar);
  505.     tf_stars[planet->pstar][ENEMY]=1;
  506.   } 
  507.   else 
  508.   { /*use present tf*/
  509.     new_tf = 1;
  510.     while ((tf[ENEMY][new_tf].dest != planet->pstar) ||
  511.        (tf[ENEMY][new_tf].eta != 0))
  512.       new_tf++;
  513.   }
  514.  
  515.   /* Build a minimum of missile bases */
  516.   min_mb = planet->capacity/20;
  517.   while ((planet->amb == 0) && (!planet->conquered) &&
  518.        (planet->mb < min_mb) && (balance >= mb_cost))
  519.   {
  520.     balance = balance - mb_cost;
  521.     planet->mb++;
  522.   }
  523.  
  524.   /* Build an amb more */
  525.   if ((balance >= b_cost) && (planet->amb > 1) &&
  526.       (rnd(5) != 1) && (rnd(7) <= planet->amb+3)) 
  527.   {
  528.     balance = balance - b_cost;
  529.     tf[ENEMY][new_tf].b++;
  530.   }
  531.  
  532.   /* Maybe build the first one */
  533.   if ((balance >= amb_cost) && (!planet->conquered) &&
  534.       ((planet->amb < 4) || (rnd(2)==2)))
  535.   {
  536.     balance = balance - amb_cost;
  537.     planet->amb++;
  538.   }
  539.  
  540.   while (balance >= 9) 
  541.   {
  542.     switch (rnd(12))
  543.     {
  544.      case 1: /* Research something */
  545.      case 2: 
  546.       research(ENEMY, en_research, 8);
  547.       balance = balance-8;
  548.       break;
  549.      case 3: 
  550.      case 4:
  551.      case 10: /* Build some small things */
  552.       if (balance >= c_cost) 
  553.       {
  554.     balance = balance - c_cost;
  555.     tf[ENEMY][new_tf].c++;
  556.       } 
  557.       else if ((!planet->conquered) && (balance >= mb_cost)) 
  558.       {
  559.     balance = balance - mb_cost;
  560.     planet->mb++;
  561.       } 
  562.       else 
  563.       {
  564.     balance = balance - 9;
  565.     research(ENEMY, en_research, 9);
  566.       }
  567.       break;
  568.       
  569.      case 11: /* Build some transports */ 
  570.      case 12:
  571.       if (((float)planet->inhabitants/planet->capacity < 0.6) ||
  572.       ((planet->capacity >= b_cost/iu_ratio) && (planet->iu < b_cost+10)))
  573.       { /* No t's - invest instead*/
  574.     inv_amount = min(3, planet->inhabitants*iu_ratio - planet->iu);
  575.     balance = balance - inv_amount*i_cost;
  576.     planet->iu = planet->iu + inv_amount;
  577.       } 
  578.       else /*build transports*/
  579.     if(!(planet->conquered))
  580.     {
  581.       transports = min(rnd(2)+6, planet->inhabitants-1);
  582.       if (planet->iu > b_cost)
  583.         transports = min(transports,planet->iu - b_cost);
  584.  
  585.       balance = balance - transports;
  586.       planet->inhabitants = planet->inhabitants - transports;
  587.       planet->iu = min(planet->iu-transports,planet->inhabitants*iu_ratio);
  588.       tf[ENEMY][new_tf].t = tf[ENEMY][new_tf].t + transports;
  589.     }
  590.       break;
  591.      default: /* Just invest some */
  592.       inv_amount = min(3,planet->inhabitants*iu_ratio - planet->iu);
  593.       balance = balance - i_cost*inv_amount;
  594.       planet->iu = planet->iu + inv_amount;
  595.       break;
  596.       
  597.     } /*switch */
  598.   } /*while */
  599.   zero_tf(ENEMY,new_tf);
  600.   research(ENEMY,en_research,balance);
  601. }
  602.